package com.example.httpdemo.net.token;

import com.example.httpdemo.model.RefreshTokenModel;
import com.example.httpdemo.model.RefreshTokenRequestModel;
import com.example.httpdemo.net.ApiService;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;

import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class AuthInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();

        // 如果请求不需要认证，直接放行
        if (originalRequest.header("No-Authentication") != null) {
            return chain.proceed(originalRequest);
        }

        // 获取token
        String accessToken = TokenManager.getInstance().getAccessToken();

        // 如果token为空，直接放行（可能是首次请求）
        if (accessToken == null) {
            return chain.proceed(originalRequest);
        }

        // 如果token未过期，添加token并放行
        if (!TokenManager.getInstance().isTokenExpired()) {
            Request authorisedRequest = originalRequest.newBuilder()
                    .header("Authorization", "Bearer " + accessToken)
                    .build();
            return chain.proceed(authorisedRequest);
        }

        // 如果token已过期，同步刷新token
        synchronized (this) {
            // 再次检查，防止多个请求同时刷新
            if (TokenManager.getInstance().isTokenExpired()) {
                try {
                    // 刷新token
                    refreshToken();
                } catch (Exception e) {
                    // 刷新失败，跳转到登录页面或处理错误
                    TokenManager.getInstance().clearTokens();
                    // 可以在这里发送广播通知应用需要重新登录
                    return chain.proceed(originalRequest);
                }
            }

            // 使用新token重试请求
            String newToken = TokenManager.getInstance().getAccessToken();
            Request newRequest = originalRequest.newBuilder()
                    .header("Authorization", "Bearer " + newToken)
                    .build();
            return chain.proceed(newRequest);
        }
    }

    private void refreshToken() throws IOException {
        // 创建不携带token的Retrofit实例
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new HttpLoggingInterceptor())
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.example.com/")
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build();

        // 创建刷新token的API服务
        ApiService authService = retrofit.create(ApiService.class);

        // 同步刷新token
        RefreshTokenRequestModel refreshTokenRequest = new RefreshTokenRequestModel(
                TokenManager.getInstance().getRefreshToken()
        );
        Call<RefreshTokenModel> call = authService.refreshToken(refreshTokenRequest);

        retrofit2.Response<RefreshTokenModel> response = call.execute();

        if (response.isSuccessful() && response.body() != null) {
            RefreshTokenModel tokenResponse = response.body();
            // 更新token
            TokenManager.getInstance().updateTokens(
                    tokenResponse.getAccessToken(),
                    tokenResponse.getRefreshToken(),
                    tokenResponse.getExpiresIn()
            );
        } else {
            throw new IOException("Failed to refresh token");
        }
    }
}